package com.itlong.cloud.utils.file;


import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.lang.StringUtil;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.drew.metadata.exif.ExifDirectoryBase;

import javax.imageio.ImageIO;
import javax.tools.Tool;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.Iterator;
import java.util.Map;

/**
 * <desc>
 *  旋转上传图片角度问题工具类
 * </desc>
 *
 * @author: chengshican
 *  @Date: 2020-08-21 17:36
 *
 */
public class ImgageUtil {



    /**
     *
     * @功能:解析base64图片编码，判断是否有旋转
     * @param bts base64图片编码
     * @param format 图片格式
     *
     */
    public static byte[] stringToImage(byte[] bts,String format){

        InputStream is = new ByteArrayInputStream(bts);
        try {
            //获取照片的Exif信息
            Metadata metadata = JpegMetadataReader.readMetadata(is);
            Directory exif = metadata.getFirstDirectoryOfType(ExifDirectoryBase.class);

            //输出从图片获取到的相关信息
            Iterable<Directory> ites =  metadata.getDirectories();
            for (Directory directory : ites) {
                Iterator<Tag> tags = directory.getTags().iterator();
                while(tags.hasNext()){
                    Tag tag = (Tag) tags.next();
                    System.out.println(tag);
                }
            }
            //获取照片拍摄方向
            String type = exif.getString(ExifDirectoryBase.TAG_ORIENTATION);
            //图片正常情况下，type=1,测试正常图片旋转，请修改case 条件为 1
            if(!type.equals(null)){//判断拍摄方向是否为空
                switch (Integer.parseInt(type)) {
                    case 3://要进行180度旋转
                        byte[] bytes = rotateImg(bts , 180.0 , format);
                        return bytes;
                    case 6://要进行90度旋转
                        byte[] bytes1 = rotateImg(bts , 90.0 , format);
                        return bytes1;
                    case 8://要进行-90度旋转
                        byte[] bytes2 = rotateImg(bts , -90.0 , format);
                        return bytes2;
                    default :
                        return bts;
                }
            }else{
                return  bts;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    
    /**
    *<desc>
    * @功能:矫正图片旋转，返回byte[]
    *</desc>
    *
    * @Author  chengshican
    * @Date   2020-08-21 17:59
     * @param angle
     * @param format
     * @throws IOException void
    * @Return      
    * @Exception   
    * 
    */
    public static byte[] rotateImg(byte[] bytes , double angle , String format) throws IOException {
        InputStream input = new ByteArrayInputStream(bytes);
        BufferedImage old_img = ImageIO.read(input);
        int width = old_img.getWidth();
        int height = old_img.getHeight();
        double[][] newPositions = new double[4][];
        newPositions[0] = calculatePosition(0, 0, angle);
        newPositions[1] = calculatePosition(width, 0, angle);
        newPositions[2] = calculatePosition(0, height, angle);
        newPositions[3] = calculatePosition(width, height, angle);
        double minX = Math.min(
                Math.min(newPositions[0][0], newPositions[1][0]),
                Math.min(newPositions[2][0], newPositions[3][0])
        );
        double maxX = Math.max(
                Math.max(newPositions[0][0], newPositions[1][0]),
                Math.max(newPositions[2][0], newPositions[3][0])
        );
        double minY = Math.min(
                Math.min(newPositions[0][1], newPositions[1][1]),
                Math.min(newPositions[2][1], newPositions[3][1])
        );
        double maxY = Math.max(
                Math.max(newPositions[0][1], newPositions[1][1]),
                Math.max(newPositions[2][1], newPositions[3][1])
        );
        int newWidth = (int)Math.round(maxX - minX);
        int newHeight = (int)Math.round(maxY - minY);
        BufferedImage new_img = new BufferedImage(newWidth, newHeight , BufferedImage.TYPE_INT_BGR);

        Graphics2D g = new_img.createGraphics();

        g.setRenderingHint(
                RenderingHints.KEY_INTERPOLATION,
                RenderingHints.VALUE_INTERPOLATION_BILINEAR
        );
        g.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON
        );
        double w = newWidth / 2.0;
        double h = newHeight / 2.0;

        g.rotate(Math.toRadians(angle), w, h);
        int centerX = (int)Math.round((newWidth - width) / 2.0);
        int centerY = (int)Math.round((newHeight - height) / 2.0);

        g.drawImage(old_img, centerX, centerY, null);
        g.dispose();
        //新建流。
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        //利用ImageIO类的write方法，将BufferedImage以png图片的数据模式写入流。
        ImageIO.write(new_img, format, baos);
        return baos.toByteArray();
    }
    private static double[] calculatePosition(double x, double y, double angle){
        angle = Math.toRadians(angle);
        double nx = (Math.cos(angle) * x) - (Math.sin(angle) * y);
        double ny = (Math.sin(angle) * x) + (Math.cos(angle) * y);
        return new double[] {nx, ny};
    }
}
